# 利用中点算法绘制两条直线，分别是：L1(Point(20, 10), Point(100, 180))， L2(Point(-50, 100), Point(100, -50))。

import numpy as np
import matplotlib.pyplot as plt

width = 480
height = 480


def axis_shift(x, y):
    # 到坐标原点
    x = x + width // 2
    y = height // 2 - y
    return x, y


def draw(img, points, color=(255, 255, 255)):
    for (x, y) in points:
        x0, y0 = axis_shift(x, y)
        img[y0, x0, :] = color
    return img


def MPLineX(x1, y1, x2, y2):
    """
    绘制0<=k<=1的直线
    """
    p = []
    dx = x2 - x1
    dy = y2 - y1
    e = dx - 2 * dy
    up_inc = 2 * dx - 2 * dy
    down_inc = -2 * dy
    y = y1
    for x in range(x1, x2 + 1):
        p.append((x, y))
        if e < 0:
            y += 1
            e += up_inc
        else:
            e += down_inc
    return p


def MPLine(x1, y1, x2, y2):
    points = []
    # 确保x1在左，x2在右
    if x1 > x2:
        x1, y1, x2, y2 = x2, y2, x1, y1

    dx = abs(x2 - x1)
    dy = abs(y2 - y1)
    if dx >= dy:    # x 主位移
        dy = y2 - y1
        if dy >= 0:     # 增函数（k==[0,1]）
            p = MPLineX(x1, y1, x2, y2)
            points += p
        else:   # 减函数（k==[0, -1]）,y方向翻转所有点，让它变成k=[0,1]的直线，再翻转回去，可以免去计算中点公式
            y1, y2 = -y1, -y2
            p = MPLineX(x1, y1, x2, y2)
            # p中的所有点翻转回来
            for (px, py) in p:
                points.append((px, -py))

    return points


# 加载或创建一个图像
img = np.zeros((height, width, 3), dtype=np.uint8)  # 创建一个256x256的黑色画布

# 绘制线段
points1 = MPLine(20, 10, 200, 80)
img = draw(img, points1, (255,255,255))
points2 = MPLine(-20, 10, 200, -80)
img = draw(img, points2, (255,0,0))
points3 = MPLine(-20, 10, 200, 10)
img = draw(img, points3, (255,255,0))


# 显示图像
plt.imshow(img)
plt.show()
